package ar.edu.unicen.pladema.ui.model;

import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;

import ar.edu.unicen.pladema.ui.model.points.AxisPoint;
import ar.edu.unicen.pladema.ui.model.points.ScreenPoint;

public class EjeCoordenadas {
	/** El margen que se va a dejar para dibujar */
	private static int MARGIN=5;
	/** El margen que se va a dejar para las letras */
	private static int FONT=25;
	/** Cantidad de numeros sobre el eje */
	private static int CNUM=10;
	/** Alto del paño */
	private int h;
	/** Ancho del paño */
	private int w;
	/** punto en el paño para el maximo valor de y */
	private int pYMax;
	/** punto en el paño para el maximo valor de x */
	private int pXMax;
	/** punto en el paño para el cero de y */
	private int p0Y;
	/** punto en el paño para el cero de x */
	//private int p0X;
	/** alto disponible en el paño */
	private int ph;
	/** ancho disponible en el paño */
	private int pw;
	/** escala para y */
	private int ey;
	/** escala para x */
	private int ex;
	/** modificador de escala para y */
	private double mey;
	/** modificador de escala para x */
	private double mex;
	public EjeCoordenadas() {
		this.ex = 10;
		this.ey = 10;
		this.w = 10;
		this.h = 10;
	}
	public void setScala(int vx, int vy) {
		this.ex = vx;
		this.ey = vy;
		calcVars();
	}
	public int getScalaX() { return this.ex; }
	public int getScalaY() { return this.ey; }
	
	public void setSize(int sx, int sy) {
		this.w = sx - 25;
		this.h = sy;
		calcVars();
	}
	private void calcVars() {
		//p0X = MARGIN + FONT;
		p0Y = h - (MARGIN + FONT);
		
		pXMax = w - MARGIN;
		pYMax = MARGIN;
		
		pw = w - (MARGIN + FONT + MARGIN);
		ph = h - (MARGIN + FONT + MARGIN);
		
		mex = new Double(pw) / new Double(ex);
		mey = new Double(ph) / new Double(ey);
	}
	public int getX(int v) {
		double r = (mex * v) + MARGIN + FONT;
		return (new Double(r)).intValue();
	}
	public int getRawX(int v) {
		double r = v - (MARGIN + FONT);
		r = r / mex;
		return (new Double(r)).intValue();
	}
	public int getY(int v) {
		double r = p0Y - (mey * v);
		return (new Double(r)).intValue();
	}
	public int getRawY(int v) {
		double r = (p0Y - v) / mey;
		return (new Double(r)).intValue();
	}
	public void drawAxis(GC gc) {
		gc.drawLine(getX(0), getY(0), pXMax, getY(0));
		gc.drawLine(getX(0), getY(0), getX(0), pYMax);
		drawThickPoint(gc, 0, 0);
		drawScalePoint(gc);
	}
	private void drawScalePoint(GC gc) {
		int jumpX = ex / CNUM;
		int startX = jumpX;
		while (getX(startX) <= pXMax) {
			drawThickPoint(gc, startX, 0);
			gc.drawString(Integer.toString(startX), getX(startX) , getY(0)+1);
			startX += jumpX;
		}
		int jumpY = ey /CNUM;
		int startY = jumpY;
		while (startY <= ey) {
			drawThickPoint(gc, 0, startY);
			gc.drawString(Integer.toString(startY), 0 , getY(startY));
			startY += jumpY;
		}
	}
	private void drawThickPoint(GC gc, int x, int y) {
		drawThickPoint(gc, x, y, new Color(gc.getDevice(), 0,0,0));
	}
	private void drawThickPoint(GC gc, int x, int y, Color color) {
		gc.setForeground(color);
		int px = getX(x);
		int py = getY(y);
		gc.drawPoint(px, py);
		gc.drawPoint(px-1, py-1);
		gc.drawPoint(px-1, py+1);
		gc.drawPoint(px-1, py);
		gc.drawPoint(px+1, py-1);
		gc.drawPoint(px+1, py+1);
		gc.drawPoint(px+1, py);
		gc.drawPoint(px, py-1);
		gc.drawPoint(px, py+1);
		gc.drawPoint(px, py);
		
	}
	private void drawFatThickPoint(GC gc, int x, int y, Color color) {
		gc.setForeground(color);
		int px = getX(x);
		int py = getY(y);
		gc.drawPoint(px, py);
		gc.drawPoint(px-1, py-1);
		gc.drawPoint(px-1, py+1);
		gc.drawPoint(px-1, py);
		gc.drawPoint(px+1, py-1);
		gc.drawPoint(px+1, py+1);
		gc.drawPoint(px+1, py);
		gc.drawPoint(px, py-1);
		gc.drawPoint(px, py+1);
		gc.drawPoint(px, py);
		gc.drawPoint(px, py+2);
		gc.drawPoint(px, py-2);
		gc.drawPoint(px+2, py);
		gc.drawPoint(px-2, py);
	}
	public void drawPoints(GC gc, PointManager pointManager) {
		for (AxisPoint sp : pointManager.getPoints()) {
			drawFatThickPoint(gc, sp.getX(), sp.getY(), new Color(gc.getDevice(), 255,0,0));
		}
		
	}
	public AxisPoint convertPoint(ScreenPoint from) {
		AxisPoint r = new AxisPoint(getRawX(from.getX()), getRawY(from.getY()));
		return r;
	}
}
